package itdep.jsf.tag;

import com.sun.facelets.FaceletContext;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagConfig;
import com.sun.facelets.tag.TagHandler;
import ga.domain.services.EntityService;
import itdep.jsf.internal.SelectModelUtils;

import javax.el.ELException;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.component.UISelectItems;
import javax.faces.model.SelectItem;
import java.io.IOException;
import java.util.List;

/**
 * @author Ivan Khalopik
 * @version $Revision: 23 $ $Date: 2010-06-19 09:36:09 +0000 (Sat, 19 Jun 2010) $
 * @since 2.0
 */
public class SelectItemsTag extends TagHandler {
	protected final TagAttribute source;
	protected final TagAttribute format;
	protected final TagAttribute parameters;
	protected final TagAttribute disabled;

	public SelectItemsTag(TagConfig config) {
		super(config);
		source = getAttribute("source");
		format = getAttribute("format");
		parameters = getAttribute("parameters");
		disabled = getAttribute("disabled");
	}

	public void apply(FaceletContext faceletContext, UIComponent parent) throws IOException, FacesException, ELException {
		if (disabled != null && !disabled.getBoolean(faceletContext)) {
			final List<?> values = getValues(faceletContext);
			final String formatValue = format.getValue(faceletContext);
			final Object parametersValue = parameters.getObject(faceletContext);
			final List<SelectItem> items = formatValue != null ?
					SelectModelUtils.buildFormatted(values, formatValue, (String[]) parametersValue) :
					SelectModelUtils.buildSimple(values);
			final UISelectItems selectItems = new UISelectItems();
			selectItems.setValue(items);
			parent.getChildren().clear(); //todo: do not clear, group attribute
			parent.getChildren().add(selectItems);
		}
	}

	private List<?> getValues(FaceletContext faceletContext) {
		final Object sourceValue = source.getObject(faceletContext);
		if (sourceValue instanceof EntityService) {
			return ((EntityService) sourceValue).getEntities();
		} else if (sourceValue instanceof List) {
			return (List) sourceValue;
		}
		throw new IllegalArgumentException("source attribute must be of type List or EntityService");
	}

}
